/***************************************************************************
 创建者: hualei
 开始时间: 2018.9.10
 copyright: (C) 深圳市华友高科有限公司
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2018.9.10 类的具体实现代码编写

 ***************************************************************************
 *  @file ftpmanage.h
 *  功能: 提供FTP 登录丶下载丶上传丶删除丶下载目录文件操作的接口实现
 *
 ***************************************************************************/
#ifndef FTPMANAGE_H
#define FTPMANAGE_H

#include <QWidget>
#include <QFile>
#include <QObject>
#include <QHash>
#include "ftpmanage_global.h"

class QFtp;
class QUrlInfo;

/**
 * @brief The FtpManage class       全局对象，外部使用　　提供FTP 登录丶下载丶上传丶删除丶下载目录文件操作的接口实现
 */
class FTPMANAGESHARED_EXPORT FtpManage : public QWidget
{
    Q_OBJECT

public:

    /**
     * @brief FtpManage         构造函数
     * @param parent            继承父类
     */
    FtpManage(QWidget *parent = 0);
    ~FtpManage();

public:

    bool isDownLoadFileStatus();

    /**
     * @brief ftpLogin      登录至FTP服务器接口
     * @param host          主机IP
     * @param port          端口号
     * @param userName      登录用户名
     * @param passwd        登录密码
     * @return              当前ID
     */
    int ftpLogin(const QString& host, int port, const QString& userName, const QString& passwd);

    /**
     * @brief ftpPutFile    上传文件至FTP服务器
     * @param fileName      文件名
     * @param clientPath    文件位于客户端的目录
     * @param serverPath    FTP保存文件的目录
     * @return              当前指令ID
     */
    int ftpPutFile(const QString& fileName, const QString& clientPath, const QString& serverPath);

    /**
     * @brief ftpGetFile                从FTP下载文件
     * @param fileName                  文件名
     * @param clientAbsolutePath        保存文件的客户端目录
     * @param serverAbsolutePath        下载文件在FTP服务器的目录
     * @return                          Success:指令ID  Fail:-1
     */
    int ftpGetFile(const QString& fileName, const QString& clientAbsolutePath, const QString& serverAbsolutePath);

    /**
     * @brief ftpRemoveFile     从FTP服务器上删除文件
     * @param fileName          要删除的文件名
     * @param path              文件在FTP的路径
     * @return                  Success:指令ID  Fail:-1
     */
    int ftpRemoveFile(const QString& fileName, const QString& path);

    /**
     * @brief getFileInDirectory        从FTP服务器上下载目录下所有文件
     * @param serverDirectoryPath       FTP服务器目录路径
     * @param clientPath                保存下载文件的客户端目录路径
     * @return                          Success:指令ID  Fail:-1
     */
    int getFileInDirectory(const QString& serverDirectoryPath, const QString& clientPath);

    /**
     * @brief setLoginFileGetFlag       设置登录时下载文件标识
     * @param status                    要设置的标识状态
     */
    void setLoginFileGetFlag(bool status);

    /**
     * @brief setGetDirFlag             设置下载目录标识
     * @param status                    要设置的标识状态
     */
    void setGetDirFlag(bool status);

    /**
     * @brief isGetDir                  是否是下载目录
     * @return                          状态信息
     */
    bool isGetDir();

    /**
     * @brief isLoginDirFlag            是否是登录文件目录
     * @return                          状态信息
     */
    bool isLoginDirFlag();

    /**
     * @brief isFtpLoginSuccess         是否FTP登录成功
     * @return                          状态信息
     */
    bool isFtpLoginSuccess();

    /**
     * @brief getServerFileListInfo     获取服务器文件列表信息
     * @param path
     */
    void getServerFileListInfo(const QString &path);
private:
     int checkFtpState();

private:

    /**
     * @brief isDirectory               FTP目录下的所有文件及目录信息
     */
    QHash<QString, bool> isDirectory;

    /**
     * @brief listFtpDirectory          保存下载FTP目录下所有文件时目录路径
     */
    QString listFtpDirectory;

    /**
     * @brief listGetFileClientPath     保存接收文件的目录路径
     */
    QString listGetFileClientPath;

private:

    /**
     * @brief _FromSpecialEncoding      有FTP端编码转本地编码
     * @param InputStr                  要转换的字符串
     * @return                          Success:转换成功的本地编码字符串, fial:空字符串
     */
    QString _FromSpecialEncoding(const QString &InputStr);

    /**
     * @brief _ToSpecialEncoding        put get等上传文件时，转换为FTP端编码
     * @param InputStr                  要转换的字符串
     * @return                          Success:转换成功的FTP端编码字符串, fial:空字符串
     */
    QString _ToSpecialEncoding(const QString &InputStr); 

public slots:

    /**
     * @brief ftpCommandStartSlot   命令开始指令槽函数
     */
    void ftpCommandStartSlot(int);

    /**
     * @brief ftpCommandFinishSlot  命令执行完成槽函数
     * @param error                 完成状态
     */
    void ftpCommandFinishSlot(int, bool error);

    /**
     * @brief updateDataTransferProgress        传输进度条
     */
    void updateDataTransferProgress(qint64, qint64 );

    /**
     * @brief addToList             将服务器上的文件添加到部件中
     * @param urlInfo               文件信息
     */
    void addToList(const QUrlInfo &urlInfo);

    /**
     * @brief stateChangedSlot      连接状态切换响应槽函数
     * @param state                 状态信息
     */
    void stateChangedSlot(int state);

signals:
    void ftpError_signal(QString);

    /**
     * @brief updateProgress   参数一：已经读取的数据大小， 参数二：需要读取的数据总大小
     */
    void updateProgress(qint64,qint64);

    /**
     * @brief getFileInServerDirectory      获取下载目录下所有文件信息信号
     * @param isDirectory                   目录下文件信息， QString: 文件、目录名  bool：是否位文件-false：文件  true:目录
     * @param listFtpDirectory              FTP服务器目标目录路径
     * @param listGetFileClientPath         Client客户端保存下载文件的路径
     */
    void getFileInServerDirectory(const QHash<QString, bool> isDirectory, const QString& listFtpDirectory, const QString& listGetFileClientPath);

    /**
     * @brief isConnectToHost               是否成功联通到主机
     * @param status                        联通状态： false-失败   true-成功
     * @param message                       状态信息
     */
    void isConnectToHost(bool status,const QString& message);

    /**
     * @brief isLogined                     是否成功登录到FTP服务器
     * @param status                        登录状态：  false-失败   true-成功
     * @param message                       状态信息
     */
    void isLogined(bool status, const QString&  message);

    /**
     * @brief isGetFile                     是否成功下载文件
     * @param status                        下载状态：  false-失败   true-成功
     * @param message                       状态信息
     */
    void isGetFile(bool status, const QString& message);

    /**
     * @brief isPutFile                     是否成功上传文件
     * @param status                        上传状态：  false-失败   true-成功
     * @param message                       状态信息
     */
    void isPutFile(bool status, const QString& message);

    /**
     * @brief isRemoveFile                  是否成功删除文件
     * @param status                        删除状态：  false-失败   true-成功
     * @param message                       状态信息
     */
    void isRemoveFile(bool status, const QString& message);

    /**
     * @brief isGetDirectoryFile            是否成功下载目录文件
     * @param status                        下载状态：  false-失败   true-成功
     * @param message                       状态信息
     */
    void isGetDirectoryFile(bool status, const QString& message);

    /**
     * @brief currentGetFile                当前下载文件
     * @param filePath                      文件路径
     */
    void currentGetFile(const QString& filePath);

    /**
     * @brief currentPutFile                当前上传文件
     * @param filePath                      文件路径
     */
    void currentPutFile(const QString& filePath);

    /**
     * @brief showFtpGetDialog              显示下载窗口
     */
    void showFtpGetDialog();

    /**
     * @brief showFtpPutDialog              显示上传窗口
     */
    void showFtpPutDialog();

private:

    /**
     * @brief ftp           FTP客户端对象
     */
    QFtp *ftp;

    /**
     * @brief file          文件对象
     */
    QFile *file;

private:

    /**
     * @brief getDirectoryFlag          下载目录标识， true：下载目录    false：下载文件
     */
    bool getDirectoryFlag;

    /**
     * @brief loginGetDirFlag           登录前配置文件下载标识   false:其他目录下载  true: 登录时配置文件目录下载
     */
    bool loginGetDirFlag;

    /**
     * @brief isFtpLoginSuccessed       FTP登录状态
     */
    bool isFtpLoginSuccessed;

    QString host_last;
    int port_last;
    QString userName_last;
    QString passwd_last;
    bool isDownLoadFile;

};

#endif // FTPMANAGE_H
